package cn.wangchao.basic.service.impl;

import cn.wangchao.basic.constants.BaseConstant;
import cn.wangchao.basic.dto.RegisterDto;
import cn.wangchao.basic.exception.BusinessException;
import cn.wangchao.basic.service.IVerifyCodeService;
import cn.wangchao.basic.util.SmsUtils;
import cn.wangchao.basic.util.StrUtils;
import cn.wangchao.basic.util.VerifyCodeUtils;
import cn.wangchao.user.domain.User;
import cn.wangchao.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String imageCode(String key) {
        if (!StringUtils.hasLength(key)){
            throw new BusinessException("不能为空,你再这样滚远点");
        }//生成code
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //redis保存
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        return VerifyCodeUtils.VerifyCode(100,38,code);
    }

    @Override
    public void smsCode(RegisterDto dto) {
        String phone = dto.getPhone();
        String codeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
//        1.空校验
        if (StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(codeKey)
                || StringUtils.isEmpty(imageCodeValue)
        ){
            throw new BusinessException("参数不能为空,请核实!!");
        }
//        2.校验图形验证码，根据imageCodeKey从redis获取图形验证码
        Object imageCodeData = redisTemplate.opsForValue().get(codeKey);
        if (imageCodeData == null){
//        。获取不到 图形验证码过期，重新获取
            throw new BusinessException("图形验证码过期，请重新获取!");
        }
//        。获取到了，比对图形验证码是否正确,并且不区分大小写
        if (!imageCodeData.toString().equalsIgnoreCase(imageCodeValue)){
//                - 不正确，提示输入图形验证码错误
            throw new BusinessException("图形验证码错误，请重新输入!");
        }
//                - 正确，往下走
//        3.校验手机号是否注册过了
        User user = userMapper.loadByphone(phone);
        if (user != null){
//        。注册过了，滚去登录
            throw new BusinessException("用户已存在,请直接登录,如忘记密码请点击找回!");
        }
//        。没有注册过，往下走
//        二：短信验证码逻辑
//        1.根据手机号拼接key，159:register，从redis获取曾今可能发送的短信验证码
        String key = BaseConstant.RegisterConstants.REGISTER_SMS_PREFIX +phone;
        Object smsCodeData = redisTemplate.opsForValue().get(key);
        //提前声明短信验证码
        String smsCode = "";

        if (smsCodeData != null){
//        1.1 获取到了
            String[] str = smsCodeData.toString().split(":");
            Long time = Long.valueOf(str[1]);
//        1.1.1 校验是否过了一分钟重发时间 value  9527:232468742341657213
            if (System.currentTimeMillis() - time <= 1*60*1000){
//        。小于一分钟  哥屋恩
                throw new BusinessException("鸡掰,甘妮娘,斯拉斯拉的!!");
            }
//        。大于一分中 （还没有到3分钟，验证码还有效），
//        使用还没过期的验证码，刷新过期时间
            smsCode = str[0];
        }else {
//        1.2 获取不到
//        1.2.1.生成新的短信验证码
            smsCode = StrUtils.getComplexRandomString(4);
        }

//        3.存储redis 设置一个过期时间
        String smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(key,smsCodeValue,3, TimeUnit.MINUTES);
//        4.发送短信
        //SmsUtils.sendSms(phone,"你的短信验证码为:" +smsCode+ "。请尽快登录哦");
        System.out.println("你的短信验证码为:" + smsCode + "。请尽快登录哦");
    }
}
